package com.gmrz.uap.datastatistics;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.gmrz.uap.authmetadata.AuthMetadataService;
import com.gmrz.uap.cfg.SystemConst;
import com.gmrz.uap.common.DBCommon;
import com.gmrz.uap.common.ServiceSupport;
import com.gmrz.uap.dict.DictConst;
import com.gmrz.uap.dict.DictService;
import com.gmrz.uap.job.TaskConst;
import com.gmrz.uap.model.*;
import com.gmrz.uap.tenant.TenantService;
import com.gmrz.uap.util.Identities;
import com.jfinal.aop.Before;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;

import java.sql.Timestamp;
import java.util.*;

public class DataStatisticsService extends ServiceSupport {

    public static final DataStatisticsService me = new DataStatisticsService();

    /**
     * 对某一天的注册信息进行统计
     *
     * @param dateTime
     * @return boolean
     */
    @Before(Tx.class)
    public boolean regStatistics(DateTime dateTime) {
        List<Tenant> tenantList = TenantService.me.getAllTenants();//所有渠道
        //认证方式集合
        Dict dict = new Dict();
        dict.setData2("1");//包含注册相关的认证类型
        dict.setIsEnable("1");//是否启用
        dict.setDtId(DictConst.DICT_TYPE_STATICS_AUTH_AUTH_TYPE_ID);
        List<Dict> authTypeList = DictService.me.getDictList(dict);
        DataStatistics dataStatistics;

        for (Tenant tenant : tenantList) {
            for (Dict authType : authTypeList) {
                dataStatistics = new DataStatistics();
                dataStatistics.setTenantId(tenant.getTenantId());
                dataStatistics.setAuthType(authType.getDictText());
                dataStatistics.set(DBCommon.TABLE_DATA_STATISTICS_COLUMN_STA_DATE, dateTime.toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY));
                dataStatistics.setStaType(TaskConst.STATISTICS_KEY_REGCOUNT);
                //获取统计分析中的记录
                dataStatistics = DataStatistics.dao.findOne(dataStatistics);

                //获取注册统计当前日期总和
                Integer statisticsCount = Authenticators.dao.getRegCountByDate(dateTime.toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY), tenant.getTenantId(), authType.getDictText());
                if (null == statisticsCount) statisticsCount = 0;

                if (null == dataStatistics) {//如果数据库中不存在记录则在数据库中增加一条记录
                    dataStatistics = new DataStatistics();
                    dataStatistics.setDstcId(Identities.uuid2());
                    dataStatistics.setTenantId(tenant.getTenantId());
                    dataStatistics.setAuthType(authType.getDictText());
                    dataStatistics.setStaDate(new Timestamp(dateTime.getMillis()));
                    dataStatistics.setStaType(TaskConst.STATISTICS_KEY_REGCOUNT);
                    dataStatistics.setStaCount(statisticsCount);
                    dataStatistics.setCreatets(new Timestamp(new DateTime().getMillis()));
                    flag = dataStatistics.save();
                } else {//将统计数据保存到数据库中
                    dataStatistics.setStaCount(statisticsCount);
                    dataStatistics.setUpdatets(new Timestamp(new DateTime().getMillis()));
                    flag = dataStatistics.update();
                }

                if (!flag) {
                    throw new RuntimeException(String.format("统计%s日期的注册信息出现异常", dateTime.toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY)));
                }
            }
        }
        return flag;
    }


    /**
     * 对某一天的注销信息进行统计
     *
     * @param dateTime
     * @return boolean
     */
    @Before(Tx.class)
    public boolean logoutStatistics(DateTime dateTime) {
        List<Tenant> tenantList = TenantService.me.getAllTenants();//所有渠道
        //认证方式集合
        Dict dict = new Dict();
        dict.setData2("1");//包含注册相关的认证类型
        dict.setIsEnable("1");//是否启用
        dict.setDtId(DictConst.DICT_TYPE_STATICS_AUTH_AUTH_TYPE_ID);
        List<Dict> authTypeList = DictService.me.getDictList(dict);
        DataStatistics dataStatistics;

        for (Tenant tenant : tenantList) {
            for (Dict authType : authTypeList) {
                dataStatistics = new DataStatistics();
                dataStatistics.setTenantId(tenant.getTenantId());
                dataStatistics.setAuthType(authType.getDictText());
                dataStatistics.set(DBCommon.TABLE_DATA_STATISTICS_COLUMN_STA_DATE, dateTime.toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY));
                dataStatistics.setStaType(TaskConst.STATISTICS_KEY_LOGOUTCOUNT);
                //获取统计分析中的记录
                dataStatistics = DataStatistics.dao.findOne(dataStatistics);

                //获取注销统计当前日期总和
                Integer statisticsCount = Authenticators.dao.getLogOutCountByDate(dateTime.toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY), tenant.getTenantId(), authType.getDictText());
                if (null == statisticsCount) statisticsCount = 0;

                if (null == dataStatistics) {//如果数据库中不存在记录则在数据库中增加一条记录
                    dataStatistics = new DataStatistics();
                    dataStatistics.setDstcId(Identities.uuid2());
                    dataStatistics.setTenantId(tenant.getTenantId());
                    dataStatistics.setAuthType(authType.getDictText());
                    dataStatistics.setStaDate(new Timestamp(dateTime.getMillis()));
                    dataStatistics.setStaType(TaskConst.STATISTICS_KEY_LOGOUTCOUNT);
                    dataStatistics.setStaCount(statisticsCount);
                    dataStatistics.setCreatets(new Timestamp(new DateTime().getMillis()));
                    flag = dataStatistics.save();
                } else {//将统计数据保存到数据库中
                    dataStatistics.setStaCount(statisticsCount);
                    dataStatistics.setUpdatets(new Timestamp(new DateTime().getMillis()));
                    flag = dataStatistics.update();
                }

                if (!flag) {
                    throw new RuntimeException(String.format("统计%s日期的注销信息出现异常", dateTime.toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY)));
                }
            }
        }
        return flag;
    }


    /**
     * 对某一天的认证信息进行统计
     *
     * @param dateTime
     * @return boolean
     */
    @Before(Tx.class)
    public boolean verifyStatistics(DateTime dateTime) {
        List<Tenant> tenantList = TenantService.me.getAllTenants();//所有渠道
        //认证方式集合
        List<Dict> authTypeList = DictService.me.getDictListByDictTypeID(DictConst.DICT_TYPE_STATICS_AUTH_AUTH_TYPE_ID);
        DataStatistics dataStatistics;


        for (Tenant tenant : tenantList) {
            for (Dict authType : authTypeList) {
                dataStatistics = new DataStatistics();
                dataStatistics.setTenantId(tenant.getTenantId());
                dataStatistics.setAuthType(authType.getDictText());
                dataStatistics.set(DBCommon.TABLE_DATA_STATISTICS_COLUMN_STA_DATE, dateTime.toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY));
                dataStatistics.setStaType(TaskConst.STATISTICS_KEY_VERIFY);
                //获取统计分析中的记录
                dataStatistics = DataStatistics.dao.findOne(dataStatistics);

                //获取注销统计当前日期总和
                Integer statisticsCount = FidoLog.dao.fidoLogCountByDate(dateTime.toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY), tenant.getTenantId(), authType.getDictText());
                if (null == statisticsCount) statisticsCount = 0;

                if (null == dataStatistics) {//如果数据库中不存在记录则在数据库中增加一条记录
                    dataStatistics = new DataStatistics();
                    dataStatistics.setDstcId(Identities.uuid2());
                    dataStatistics.setTenantId(tenant.getTenantId());
                    dataStatistics.setAuthType(authType.getDictText());
                    dataStatistics.setStaDate(new Timestamp(dateTime.getMillis()));
                    dataStatistics.setStaType(TaskConst.STATISTICS_KEY_VERIFY);
                    dataStatistics.setStaCount(statisticsCount);
                    dataStatistics.setCreatets(new Timestamp(new DateTime().getMillis()));
                    flag = dataStatistics.save();
                } else {//将统计数据保存到数据库中
                    dataStatistics.setStaCount(statisticsCount);
                    dataStatistics.setUpdatets(new Timestamp(new DateTime().getMillis()));
                    flag = dataStatistics.update();
                }

                if (!flag) {
                    throw new RuntimeException(String.format("统计%s日期的认证信息出现异常", dateTime.toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY)));
                }
            }
        }
        return flag;
    }


    /**
     * 对某一天的认证器信息进行统计
     *
     * @param dateTime
     * @return boolean
     */
    @Before(Tx.class)
    public boolean aaidStatistics(DateTime dateTime) {
        List<Tenant> tenantList = TenantService.me.getAllTenants();//所有渠道
        //认证器集合
        List<AuthMetadata> authMetadataList = AuthMetadataService.me.findAll();
        DataStatistics dataStatistics;

        for (Tenant tenant : tenantList) {
            for (AuthMetadata authMetadata : authMetadataList) {
                dataStatistics = new DataStatistics();
                dataStatistics.setTenantId(tenant.getTenantId());
                dataStatistics.setAaid(authMetadata.getAaid());
                dataStatistics.set(DBCommon.TABLE_DATA_STATISTICS_COLUMN_STA_DATE, dateTime.toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY));
                dataStatistics.setStaType(TaskConst.STATISTICS_KEY_AAID);
                //获取统计分析中的记录
                dataStatistics = DataStatistics.dao.findOne(dataStatistics);

                //获取注销统计当前日期总和
                Integer statisticsCount = Authenticators.dao.getPhoneCountByDate(dateTime.toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY), tenant.getTenantId(), authMetadata.getAaid());
                if (null == statisticsCount) statisticsCount = 0;

                if (null == dataStatistics) {//如果数据库中不存在记录则在数据库中增加一条记录
                    dataStatistics = new DataStatistics();
                    dataStatistics.setDstcId(Identities.uuid2());
                    dataStatistics.setTenantId(tenant.getTenantId());
                    dataStatistics.setAaid(authMetadata.getAaid());
                    dataStatistics.setStaDate(new Timestamp(dateTime.getMillis()));
                    dataStatistics.setStaType(TaskConst.STATISTICS_KEY_AAID);
                    dataStatistics.setStaCount(statisticsCount);
                    dataStatistics.setCreatets(new Timestamp(new DateTime().getMillis()));
                    flag = dataStatistics.save();
                } else {//将统计数据保存到数据库中
                    dataStatistics.setStaCount(statisticsCount);
                    dataStatistics.setUpdatets(new Timestamp(new DateTime().getMillis()));
                    flag = dataStatistics.update();
                }

                if (!flag) {
                    throw new RuntimeException(String.format("统计%s日期的认证器信息出现异常", dateTime.toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY)));
                }
            }
        }
        return flag;
    }

    /**
     * 对某一天的交易类型信息进行统计
     *
     * @param dateTime
     * @return boolean
     */
    @Before(Tx.class)
    public boolean transTypeStatistics(DateTime dateTime) {
        List<Tenant> tenantList = TenantService.me.getAllTenants();//所有渠道
        //交易类型集合
        List<Dict> dictList = DictService.me.getDictListByDictTypeID(DictConst.DICT_TYPE_TRANS_TYPE_ID);
        DataStatistics dataStatistics;


        for (Tenant tenant : tenantList) {
            for (Dict dict : dictList) {
                dataStatistics = new DataStatistics();
                dataStatistics.setTenantId(tenant.getTenantId());
                dataStatistics.setTransType(dict.getDictText());
                dataStatistics.set(DBCommon.TABLE_DATA_STATISTICS_COLUMN_STA_DATE, dateTime.toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY));
                dataStatistics.setStaType(TaskConst.STATISTICS_KEY_TRANS_TYPE);
                //获取统计分析中的记录
                dataStatistics = DataStatistics.dao.findOne(dataStatistics);

                //获取注销统计当前日期总和
                Integer statisticsCount = FidoLog.dao.transTypeCountByDate(dateTime.toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY), tenant.getTenantId(), dict.getDictText());
                if (null == statisticsCount) statisticsCount = 0;

                if (null == dataStatistics) {//如果数据库中不存在记录则在数据库中增加一条记录
                    dataStatistics = new DataStatistics();
                    dataStatistics.setDstcId(Identities.uuid2());
                    dataStatistics.setTenantId(tenant.getTenantId());
                    dataStatistics.setTransType(dict.getDictText());
                    dataStatistics.setStaDate(new Timestamp(dateTime.getMillis()));
                    dataStatistics.setStaType(TaskConst.STATISTICS_KEY_TRANS_TYPE);
                    dataStatistics.setStaCount(statisticsCount);
                    dataStatistics.setCreatets(new Timestamp(new DateTime().getMillis()));
                    flag = dataStatistics.save();
                } else {//将统计数据保存到数据库中
                    dataStatistics.setStaCount(statisticsCount);
                    dataStatistics.setUpdatets(new Timestamp(new DateTime().getMillis()));
                    flag = dataStatistics.update();
                }

                if (!flag) {
                    throw new RuntimeException(String.format("统计%s日期的交易类型出现异常", dateTime.toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY)));
                }
            }
        }
        return flag;
    }


    /**
     * 对某一天的系统类型信息进行统计
     *
     * @param dateTime
     * @return boolean
     */
    @Before(Tx.class)
    public boolean osTypeStatistics(DateTime dateTime) {
        List<Tenant> tenantList = TenantService.me.getAllTenants();//所有渠道
        //系统类型集合
        List<Dict> dictList = DictService.me.getDictListByDictTypeID(DictConst.DICT_TYPE_APP_TYPE_ID);
        DataStatistics dataStatistics;


        for (Tenant tenant : tenantList) {
            for (Dict dict : dictList) {
                //获取当前系统类型下的版本号
                List<String> versionList = Devices.dao.getOsVersionByOsType(dict.getDictName());

                for (String version : versionList) {
                    dataStatistics = new DataStatistics();
                    dataStatistics.setTenantId(tenant.getTenantId());
                    dataStatistics.setOsType(dict.getDictName());
                    dataStatistics.setOsVersion(version);
                    dataStatistics.set(DBCommon.TABLE_DATA_STATISTICS_COLUMN_STA_DATE, dateTime.toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY));
                    dataStatistics.setStaType(TaskConst.STATISTICS_KEY_OS_TYPE);
                    //获取统计分析中的记录
                    dataStatistics = DataStatistics.dao.findOne(dataStatistics);


                    //获取当前日期总和
                    Integer statisticsCount = Devices.dao.getCountByOSTypeOSVersionDate(tenant.getTenantId(), dict.getDictName(), version, dateTime.toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY));
                    if (null == statisticsCount) statisticsCount = 0;

                    if (null == dataStatistics) {//如果数据库中不存在记录则在数据库中增加一条记录
                        dataStatistics = new DataStatistics();
                        dataStatistics.setDstcId(Identities.uuid2());
                        dataStatistics.setTenantId(tenant.getTenantId());
                        dataStatistics.setOsType(dict.getDictName());
                        dataStatistics.setOsVersion(version);
                        dataStatistics.setStaDate(new Timestamp(dateTime.getMillis()));
                        dataStatistics.setStaType(TaskConst.STATISTICS_KEY_OS_TYPE);
                        dataStatistics.setStaCount(statisticsCount);
                        dataStatistics.setCreatets(new Timestamp(new DateTime().getMillis()));
                        flag = dataStatistics.save();
                    } else {//将统计数据保存到数据库中
                        dataStatistics.setStaCount(statisticsCount);
                        dataStatistics.setUpdatets(new Timestamp(new DateTime().getMillis()));
                        flag = dataStatistics.update();
                    }

                    if (!flag) {
                        throw new RuntimeException(String.format("统计%s日期的系统类型出现异常", dateTime.toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY)));
                    }
                }
            }
        }
        return flag;
    }


    /**
     * 对某一天的手机厂商信息进行统计
     *
     * @param dateTime
     * @return boolean
     */
    @Before(Tx.class)
    public boolean deviceTypeStatistics(DateTime dateTime) {
        List<Tenant> tenantList = TenantService.me.getAllTenants();//所有渠道
        //手机厂商集合
        List<String> deviceTypeList = Devices.dao.getDeviceTypeList();
        DataStatistics dataStatistics;


        for (Tenant tenant : tenantList) {
            for (String deviceType : deviceTypeList) {
                //获取当前手机厂商下的手机型号
                List<String> deviceNameList = Devices.dao.getDeviceTypeList(deviceType);

                for (String deviceName : deviceNameList) {
                    dataStatistics = new DataStatistics();
                    dataStatistics.setTenantId(tenant.getTenantId());
                    dataStatistics.setDeviceType(deviceType);
                    dataStatistics.setDeviceName(deviceName);
                    dataStatistics.set(DBCommon.TABLE_DATA_STATISTICS_COLUMN_STA_DATE, dateTime.toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY));
                    dataStatistics.setStaType(TaskConst.STATISTICS_KEY_DEVICE_TYPE);
                    //获取统计分析中的记录
                    dataStatistics = DataStatistics.dao.findOne(dataStatistics);


                    //获取当前日期总和
                    Integer statisticsCount = Devices.dao.getCountByDeviceTypeDeviceNameDate(tenant.getTenantId(), deviceType, deviceName, dateTime.toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY));
                    if (null == statisticsCount) statisticsCount = 0;

                    if (null == dataStatistics) {//如果数据库中不存在记录则在数据库中增加一条记录
                        dataStatistics = new DataStatistics();
                        dataStatistics.setDstcId(Identities.uuid2());
                        dataStatistics.setTenantId(tenant.getTenantId());
                        dataStatistics.setDeviceType(deviceType);
                        dataStatistics.setDeviceName(deviceName);
                        dataStatistics.setStaDate(new Timestamp(dateTime.getMillis()));
                        dataStatistics.setStaType(TaskConst.STATISTICS_KEY_DEVICE_TYPE);
                        dataStatistics.setStaCount(statisticsCount);
                        dataStatistics.setCreatets(new Timestamp(new DateTime().getMillis()));
                        flag = dataStatistics.save();
                    } else {//将统计数据保存到数据库中
                        dataStatistics.setStaCount(statisticsCount);
                        dataStatistics.setUpdatets(new Timestamp(new DateTime().getMillis()));
                        flag = dataStatistics.update();
                    }

                    if (!flag) {
                        throw new RuntimeException(String.format("统计%s日期的手机厂商信息出现异常", dateTime.toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY)));
                    }
                }
            }
        }
        return flag;
    }

    /**
     * 获取一个为12月初始值为0的集合
     *
     * @return
     */
    public List<Integer> getMonthForYear() {
        List<Integer> monthList = new ArrayList<Integer>(12);
        for (int i = 0; i < 12; i++) {
            monthList.add(0);
        }
        return monthList;
    }


    public Map<String, Object> regStatisticsCharts(String staYear, String tenantId) {

        Map<String, Object> result = new HashMap<String, Object>();

        //认证类型
        Dict dictPara = new Dict();
        dictPara.setData2("1");//包含注册相关的认证类型
        dictPara.setIsEnable("1");//是否启用
        dictPara.setDtId(DictConst.DICT_TYPE_STATICS_AUTH_AUTH_TYPE_ID);
        List<Dict> authTypeList = DictService.me.getDictList(dictPara);

        //每种认证类型12个月总和的初始值
        List<Integer> staMonthList = DataStatisticsService.me.getMonthForYear();

        for (int j = 0; j < authTypeList.size(); j++) {
            Dict dict = authTypeList.get(j);
            List<Integer> monthList = DataStatisticsService.me.getMonthForYear();//12个月的初始值
            DataStatistics dataStatistics = new DataStatistics();
            dataStatistics.setStaType(TaskConst.STATISTICS_KEY_REGCOUNT);//统计类型
            // 统计日期, 年，为了使用上索引，拼接成日期; staYear+ "-01-01" ： 2018-01-01
            dataStatistics.set(DBCommon.TABLE_DATA_STATISTICS_COLUMN_STA_DATE, staYear+ "-01-01");
            dataStatistics.set(DBCommon.TABLE_DATA_STATISTICS_COLUMN_STA_DATEOver, staYear+ "-12-31");
            dataStatistics.setTenantId(tenantId);//渠道名称
            dataStatistics.setAuthType(dict.getDictText());//认证类型

            calculateDataStatistics(dataStatistics, monthList, staMonthList);//计算统计分析每个的数量及总和

            result.put(dict.getDictText(), monthList);

        }
        result.put(DataStatisticsController.STATISTICS_RESULT_KEY_ALL, staMonthList);
        return result;
    }


    public Map<String, Object> regCompareStatisticsCharts(String staYear, String tenantId) {
        Map<String, Object> result = new HashMap<String, Object>();

        //认证类型
        Dict dictPara = new Dict();
        dictPara.setData2("1");//包含注册相关的认证类型
        dictPara.setIsEnable("1");//是否启用
        dictPara.setDtId(DictConst.DICT_TYPE_STATICS_AUTH_AUTH_TYPE_ID);
        List<Dict> authTypeList = DictService.me.getDictList(dictPara);

        //每种认证类型12个月总和的初始值
        List<Integer> staMonthList = DataStatisticsService.me.getMonthForYear();


        for (int j = 0; j < authTypeList.size(); j++) {
            Dict dict = authTypeList.get(j);
            List<Integer> monthList = DataStatisticsService.me.getMonthForYear();//12个月的初始值


            DataStatistics dataStatistics = new DataStatistics();
            dataStatistics.setStaType(TaskConst.STATISTICS_KEY_REGCOUNT);//统计类型
            // 统计日期, 统计上年12月份；为了使用上索引，拼接成日期; staYear+ "-12-01" ： 2017-12-01
            dataStatistics.set(DBCommon.TABLE_DATA_STATISTICS_COLUMN_STA_DATE, Integer.parseInt(staYear) - 1 + "-12-01");
            dataStatistics.set(DBCommon.TABLE_DATA_STATISTICS_COLUMN_STA_DATEOver, Integer.parseInt(staYear) - 1 + "-12-31");
            dataStatistics.setTenantId(tenantId);//渠道名称
            dataStatistics.setAuthType(dict.getDictText());//认证类型

            //获取上一年前12份月度统计数据
            List<DataStatistics> statisticsPrvYearLastMonth = DataStatistics.dao.getStatisticsCount(dataStatistics);
            Integer staCountTmp = 0;
            if (statisticsPrvYearLastMonth != null && !statisticsPrvYearLastMonth.isEmpty()) {
                staCountTmp = statisticsPrvYearLastMonth.get(0).getStaCount();
            }

            dataStatistics = new DataStatistics();
            dataStatistics.setStaType(TaskConst.STATISTICS_KEY_REGCOUNT);//统计类型
            // 统计日期, 年，为了使用上索引，拼接成日期; staYear+ "-01-01" ： 2018-01-01
            dataStatistics.set(DBCommon.TABLE_DATA_STATISTICS_COLUMN_STA_DATE, staYear+ "-01-01");
            dataStatistics.set(DBCommon.TABLE_DATA_STATISTICS_COLUMN_STA_DATEOver, staYear+ "-12-31");
            dataStatistics.setTenantId(tenantId);//渠道名称
            dataStatistics.setAuthType(dict.getDictText());//认证类型


            calculateCompareDataStatistics(dataStatistics, monthList, staMonthList, staCountTmp);//计算环比统计分析每个的数量及总和

            result.put(dict.getDictText(), monthList);
        }

        result.put(DataStatisticsController.STATISTICS_RESULT_KEY_ALL, staMonthList);
        return result;
    }


    public Map<String, Object> logoutStatistics(String staYear, String tenantId) {
        Map<String, Object> result = new HashMap<String, Object>();

        //认证类型
        Dict dictPara = new Dict();
        dictPara.setData2("1");//包含注册相关的认证类型
        dictPara.setIsEnable("1");//是否启用
        dictPara.setDtId(DictConst.DICT_TYPE_STATICS_AUTH_AUTH_TYPE_ID);
        List<Dict> authTypeList = DictService.me.getDictList(dictPara);

        //每种认证类型12个月总和的初始值
        List<Integer> staMonthList = DataStatisticsService.me.getMonthForYear();

        for (int j = 0; j < authTypeList.size(); j++) {
            Dict dict = authTypeList.get(j);
            List<Integer> monthList = DataStatisticsService.me.getMonthForYear();//12个月的初始值
            DataStatistics dataStatistics = new DataStatistics();
            dataStatistics.setStaType(TaskConst.STATISTICS_KEY_LOGOUTCOUNT);//统计类型
            // 统计日期, 年，为了使用上索引，拼接成日期; staYear+ "-01-01" ： 2018-01-01
            dataStatistics.set(DBCommon.TABLE_DATA_STATISTICS_COLUMN_STA_DATE, staYear+ "-01-01");
            dataStatistics.set(DBCommon.TABLE_DATA_STATISTICS_COLUMN_STA_DATEOver, staYear+ "-12-31");
            dataStatistics.setTenantId(tenantId);//渠道名称
            dataStatistics.setAuthType(dict.getDictText());//认证类型

            calculateDataStatistics(dataStatistics, monthList, staMonthList);//计算统计分析每个的数量及总和

            result.put(dict.getDictText(), monthList);

        }
        result.put(DataStatisticsController.STATISTICS_RESULT_KEY_ALL, staMonthList);
        return result;
    }


    public Map<String, Object> logoutCompareStatisticsCharts(String staYear, String tenantId) {
        Map<String, Object> result = new HashMap<String, Object>();

        //认证类型
        Dict dictPara = new Dict();
        dictPara.setData2("1");//包含注册相关的认证类型
        dictPara.setIsEnable("1");//是否启用
        dictPara.setDtId(DictConst.DICT_TYPE_STATICS_AUTH_AUTH_TYPE_ID);
        List<Dict> authTypeList = DictService.me.getDictList(dictPara);

        //每种认证类型12个月总和的初始值
        List<Integer> staMonthList = DataStatisticsService.me.getMonthForYear();


        for (int j = 0; j < authTypeList.size(); j++) {
            Dict dict = authTypeList.get(j);
            List<Integer> monthList = DataStatisticsService.me.getMonthForYear();//12个月的初始值


            DataStatistics dataStatistics = new DataStatistics();
            dataStatistics.setStaType(TaskConst.STATISTICS_KEY_LOGOUTCOUNT);//统计类型
            // 统计日期, 统计上年12月份；为了使用上索引，拼接成日期; staYear+ "-12-01" ： 2017-12-01
            dataStatistics.set(DBCommon.TABLE_DATA_STATISTICS_COLUMN_STA_DATE, Integer.parseInt(staYear) - 1 + "-12-01");
            dataStatistics.set(DBCommon.TABLE_DATA_STATISTICS_COLUMN_STA_DATEOver, Integer.parseInt(staYear) - 1 + "-12-31");
            dataStatistics.setTenantId(tenantId);//渠道名称
            dataStatistics.setAuthType(dict.getDictText());//认证类型

            //获取上一年前12份月度统计数据
            List<DataStatistics> statisticsPrvYearLastMonth = DataStatistics.dao.getStatisticsCount(dataStatistics);
            Integer staCountTmp = 0;
            if (statisticsPrvYearLastMonth != null && !statisticsPrvYearLastMonth.isEmpty()) {
                staCountTmp = statisticsPrvYearLastMonth.get(0).getStaCount();
            }

            dataStatistics = new DataStatistics();
            dataStatistics.setStaType(TaskConst.STATISTICS_KEY_LOGOUTCOUNT);//统计类型
            // 统计日期, 年，为了使用上索引，拼接成日期; staYear+ "-01-01" ： 2018-01-01
            dataStatistics.set(DBCommon.TABLE_DATA_STATISTICS_COLUMN_STA_DATE, staYear+ "-01-01");
            dataStatistics.set(DBCommon.TABLE_DATA_STATISTICS_COLUMN_STA_DATEOver, staYear+ "-12-31");
            dataStatistics.setTenantId(tenantId);//渠道名称
            dataStatistics.setAuthType(dict.getDictText());//认证类型

            calculateCompareDataStatistics(dataStatistics, monthList, staMonthList, staCountTmp);//计算环比统计分析每个的数量及总和

            result.put(dict.getDictText(), monthList);
        }

        result.put(DataStatisticsController.STATISTICS_RESULT_KEY_ALL, staMonthList);
        return result;
    }


    public Map<String, Object> verifyStatisticsCharts(String staYear, String tenantId) {
        Map<String, Object> result = new HashMap<String, Object>();

        //认证类型
        List<Dict> authTypeList = Dict.dao.getDictByType(DictConst.DICT_TYPE_STATICS_AUTH_AUTH_TYPE_ID);

        //每种认证类型12个月总和的初始值
        List<Integer> staMonthList = DataStatisticsService.me.getMonthForYear();

        for (int j = 0; j < authTypeList.size(); j++) {
            Dict dict = authTypeList.get(j);
            List<Integer> monthList = DataStatisticsService.me.getMonthForYear();//12个月的初始值
            DataStatistics dataStatistics = new DataStatistics();
            dataStatistics.setStaType(TaskConst.STATISTICS_KEY_VERIFY);//统计类型
            // 统计日期, 年，为了使用上索引，拼接成日期; staYear+ "-01-01" ： 2018-01-01
            dataStatistics.set(DBCommon.TABLE_DATA_STATISTICS_COLUMN_STA_DATE, staYear+ "-01-01");
            dataStatistics.set(DBCommon.TABLE_DATA_STATISTICS_COLUMN_STA_DATEOver, staYear+ "-12-31");
            dataStatistics.setTenantId(tenantId);//渠道名称
            dataStatistics.setAuthType(dict.getDictText());//认证类型

            calculateDataStatistics(dataStatistics, monthList, staMonthList);//计算统计分析每个的数量及总和

            result.put(dict.getDictText(), monthList);

        }
        result.put(DataStatisticsController.STATISTICS_RESULT_KEY_ALL, staMonthList);
        return result;
    }

    /**
     * 计算某一个时间与当前时间天数的集合
     *
     * @param startDate 需要计算的日期
     * @return 时间集合，精确到天
     */
    public List<String> differDays(DateTime startDate) {
        long betweenDay = DateUtil.between(startDate.toDate(), new Date(), DateUnit.DAY);

        List<String> result = new ArrayList<String>();

        if (startDate.isAfterNow()) {//如果参数的日期大于当前日期则返回
            return result;
        }

        for (int i = 0; i < betweenDay; i++) {
            result.add(startDate.plusDays(i).toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY));
        }
        return result;
    }

    public List<String> differBeforeDays(DateTime startDate) {
        long betweenDay = DateUtil.between(startDate.toDate(), new Date(), DateUnit.DAY);

        List<String> result = new ArrayList<String>();

        if (startDate.isAfterNow()) {//如果参数的日期大于当前日期则返回
            return result;
        }

        for (int i = -1; i < betweenDay; i++) {
            result.add(startDate.plusDays(i).toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY));
        }
        return result;
    }

    /**
     * 计算某一年与当前年的年数集合
     *
     * @param year 年
     * @return 年数集合
     */
    public List<Integer> differYears(int year) {
        List<Integer> result = new ArrayList<Integer>();
        int currYear = new DateTime().getYear();
        int diffYears = currYear - year;
        for (int i = 0; i < diffYears; i++) {
            result.add(year + i);
        }
        result.add(currYear);
        return result;
    }

    /**
     * 获取1-5分钟随机毫秒数
     *
     * @return
     */
    public int getRandomSleepMinutes() {
        return (int) (Math.random() * 5 + 1) * 60000;
    }

    /**
     * 计算统计分析每个的数量及总和
     *
     * @param dataStatistics
     * @param monthList
     * @param staMonthList
     */
    public void calculateDataStatistics(DataStatistics dataStatistics, List<Integer> monthList, List<Integer> staMonthList) {
        //获取当前年份月度统计数据
        List<DataStatistics> statisticsDataList = DataStatistics.dao.getStatisticsCount(dataStatistics);

        for (int i = 0; i < statisticsDataList.size(); i++) {
            // minusMonths(1)：上个月，getMonthOfYear()：获取月份
            int month = new DateTime(statisticsDataList.get(i).getData1()).minusMonths(1).getMonthOfYear();
            if (month == 12) {
                month = 0;
            }

            monthList.set(month, statisticsDataList.get(i).getStaCount());
            staMonthList.set(month, staMonthList.get(month) + statisticsDataList.get(i).getStaCount());//计算每种认证方式的月度总和
        }
    }

    /**
     * 计算环比统计分析每个的数量及总和
     *
     * @param dataStatistics
     * @param monthList
     * @param staMonthList
     */
    public void calculateCompareDataStatistics(DataStatistics dataStatistics, List<Integer> monthList, List<Integer> staMonthList, Integer staCountTmp) {
        //获取当前年份月度统计数据
        List<DataStatistics> statisticsDataList = DataStatistics.dao.getStatisticsCount(dataStatistics);

        for (int i = 0; i < statisticsDataList.size(); i++) {
            //获取统计数据
            int month = new DateTime(statisticsDataList.get(i).getData1()).minusMonths(1).getMonthOfYear();
            if (month == 12) {
                month = 0;
            }

            int differenceValue = statisticsDataList.get(i).getStaCount() - staCountTmp;
            monthList.set(month, differenceValue);
            staMonthList.set(month, staMonthList.get(month) + differenceValue);//计算每种认证方式的月度总和
            staCountTmp = statisticsDataList.get(i).getStaCount();
        }
    }

    /**
     * 获取认证类型
     *
     * @return 认证类型集合
     */
    public List<Dict> getAuthTypes(boolean flag) {
        Dict dict = new Dict();
        if (flag) {//是否为注册相关的认证类型
            dict.setData2("1");//包含注册相关的认证类型
        }
        dict.setDtId(DictConst.DICT_TYPE_STATICS_AUTH_AUTH_TYPE_ID);
        dict.setIsEnable("1");//是否启用
        return DictService.me.getDictList(dict);
    }

    /**
     * 获取相差的年数集合
     *
     * @return
     */
    public List<Integer> getStaYears(String startDate, String endDate) {

        List<Integer> staYears = new ArrayList<Integer>();
        int count = 0;
        int tmpYear = 0;

        if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) {

            while (tmpYear != Integer.parseInt(endDate)) {
                tmpYear = Integer.parseInt(startDate) + count;
                count++;
                staYears.add(tmpYear);
            }

            return staYears;
        }

        DateTime earliestDate = DataStatistics.dao.getEarliestDate();
        return DataStatisticsService.me.differYears(earliestDate.getYear());//获取相差的年数集合
    }


    /**
     * 获取年度统计数据
     *
     * @param tenantId
     * @param statisticsYears
     * @param authTypeList
     * @param staType
     * @return
     */
    public Map<String, Object> getStaYear(String tenantId, List<Integer> statisticsYears, List<Dict> authTypeList, String staType) {
        Map<String, Object> result = new HashMap<String, Object>();

        for (Dict dict : authTypeList) {

            //初始化某一种认证类型的数据集合
            List<Integer> staCountArr = new ArrayList<>(statisticsYears.size());

            List<Dict> tmpAuthTypeList = new ArrayList<Dict>();
            tmpAuthTypeList.add(dict);

            for (Integer year : statisticsYears) {
                int authTypeCount = DataStatistics.dao.getRegCountForYear(tenantId, year, tmpAuthTypeList, staType);
                staCountArr.add(authTypeCount);
            }
            result.put(dict.getDictText(), staCountArr);
        }

        //每一年统计总和
        List<Integer> yearStaList = new ArrayList<>();
        for (Integer year : statisticsYears) {
            yearStaList.add(DataStatistics.dao.getRegCountForYear(tenantId, year, authTypeList, staType));
        }

        result.put(DataStatisticsController.STATISTICS_RESULT_KEY_ALL, yearStaList);

        return result;
    }

    /**
     * 获取手机型号使用排行
     *
     * @param tenantId  渠道名称
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @param page      页数
     * @param rows      行数
     * @return 手机使用排行 List<Record>
     */
    public Page<Record> getPhoneUse(String tenantId, String startDate, String endDate, int page, int rows, String sort, String order) {
        return DataStatistics.dao.getPhoneUse(tenantId, startDate, endDate, page, rows, sort, order);
    }

    /**
     * 统计注册、认证、注销每日数量
     *
     * @param tenantId  渠道名称
     * @param staType   统计类型
     * @param authType  认证类型
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @param page      页号
     * @param rows      行数
     * @param sort      排序字段
     * @param order     升序/降序
     * @return 统计数据 Page
     */
    public Page<DataStatistics> getStaDataForDay(String tenantId, String staType, String authType, String startDate, String endDate, int page, int rows, String sort, String order) {
        return DataStatistics.dao.getStaDateForDay(tenantId, staType, authType, startDate, endDate, page, rows, sort, order);
    }


    public static void main(String[] args) {
        DataStatisticsService dataStatisticsService = new DataStatisticsService();
        DateTime maxDate = new DateTime("2181-04-20");
        List<String> dateList = dataStatisticsService.differDays(maxDate);
        for (String date : dateList) {
            System.out.println(date);
        }
    }


    public List<DataStatistics> getSingleYearList() {
        return DataStatistics.dao.getSingleYearList();
    }

    @Before(Tx.class)
    public boolean certDeviceTypeStatistics(DateTime dateTime) {
        List<Tenant> tenantList = TenantService.me.getAllTenants();//所有渠道
        //手机厂商集合
        List<Dict> aaIDList = DictService.me.getDictListByDictTypeID(DictConst.DICT_TYPE_CERT_AAID);
        DataStatistics dataStatistics;
        List<String> aaIDStringList = new ArrayList<String>();
        for (Dict aaID : aaIDList) {
            String aaIdStr = aaID.getDictName();
            if (null != aaIdStr && !"".equals(aaIdStr.trim())) {
                aaIDStringList.add(aaIdStr);
            }
        }

        List<Record> certDeviceTypeStatisticBeanList = Authenticators.dao.getCertDeviceTypeStatisticBeanList(dateTime.toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY), aaIDStringList);
        if (null != certDeviceTypeStatisticBeanList && certDeviceTypeStatisticBeanList.size() > 0) {
            for (Record record : certDeviceTypeStatisticBeanList) {

                dataStatistics = new DataStatistics();
                dataStatistics.setTenantId(record.getStr("tenant_id"));
                dataStatistics.setDeviceType(record.getStr("device_type"));
                dataStatistics.setDeviceName(record.getStr("device_name"));
                dataStatistics.setAaid(record.getStr("aaid"));
                dataStatistics.set(DBCommon.TABLE_DATA_STATISTICS_COLUMN_STA_DATE, dateTime.toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY));
                dataStatistics.setStaType(TaskConst.STATISTICS_KEY_CERT_DEVICE_TYPE);
                //获取统计分析中的记录
                dataStatistics = DataStatistics.dao.findOne(dataStatistics);

                if (null == dataStatistics) {//如果数据库中不存在记录则在数据库中增加一条记录
                    dataStatistics = new DataStatistics();
                    dataStatistics.setDstcId(Identities.uuid2());
                    dataStatistics.setTenantId(record.getStr("tenant_id"));
                    dataStatistics.setDeviceType(record.getStr("device_type"));
                    dataStatistics.setDeviceName(record.getStr("device_name"));
                    dataStatistics.setAaid(record.getStr("aaid"));
                    dataStatistics.setStaDate(new Timestamp(dateTime.getMillis()));
                    dataStatistics.setStaType(TaskConst.STATISTICS_KEY_CERT_DEVICE_TYPE);
                    dataStatistics.setStaCount(record.getInt("statisticsCount"));
                    dataStatistics.setCreatets(new Timestamp(new DateTime().getMillis()));
                    flag = dataStatistics.save();
                } else {//将统计数据保存到数据库中
                    dataStatistics.setStaCount(record.getInt("statisticsCount"));
                    dataStatistics.setUpdatets(new Timestamp(new DateTime().getMillis()));
                    flag = dataStatistics.update();
                }

                if (!flag) {
                    throw new RuntimeException(String.format("统计%s日期的手机厂商信息出现异常", dateTime.toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY)));
                }
            }
        }
        return flag;
    }


    /**
     * 统计某一天根据 机构、aaid 的证书使用情况
     * @param dateTime
     * @return
     */
    @Before(Tx.class)
    public boolean certUseCaseStatistics(DateTime dateTime) {
        DataStatistics dataStatistics;
        // 统计当前日期的各个机构和aaid的证书使用情况
        List<Record> certUseCaseStatisticBeanList = Authenticators.dao.getCertUseCaseStatisticBeanList(dateTime.toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY));
        if (null != certUseCaseStatisticBeanList && certUseCaseStatisticBeanList.size() > 0) {
            for (Record record : certUseCaseStatisticBeanList) {

                dataStatistics = new DataStatistics();
                dataStatistics.setStaCount(record.getInt("statisticsCount"));
                dataStatistics.setInstCode(record.getStr("inst_code"));
                dataStatistics.setAaid(record.getStr("aaid"));
                dataStatistics.set(DBCommon.TABLE_DATA_STATISTICS_COLUMN_STA_DATE, dateTime.toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY));
                dataStatistics.setStaType(TaskConst.STATISTICS_KEY_CERT_USE_CASE);
                // 获取统计分析中的记录
                dataStatistics = DataStatistics.dao.findOne(dataStatistics);

                // 如果数据库中不存在记录则在数据库中增加一条记录
                if (null == dataStatistics) {
                    dataStatistics = new DataStatistics();
                    dataStatistics.setDstcId(Identities.uuid2());
                    dataStatistics.setStaCount(record.getInt("statisticsCount"));
                    dataStatistics.setInstCode(record.getStr("inst_code"));
                    dataStatistics.setAaid(record.getStr("aaid"));
                    dataStatistics.setStaDate(new Timestamp(dateTime.getMillis()));
                    dataStatistics.setStaType(TaskConst.STATISTICS_KEY_CERT_USE_CASE);
                    dataStatistics.setCreatets(new Timestamp(new DateTime().getMillis()));
                    flag = dataStatistics.save();
                } else {
                    // 将统计数据保存到数据库中
                    dataStatistics.setStaCount(record.getInt("statisticsCount"));
                    dataStatistics.setUpdatets(new Timestamp(new DateTime().getMillis()));
                    flag = dataStatistics.update();
                }

                if (!flag) {
                    throw new RuntimeException(String.format("统计%s日期的证书使用信息出现异常", dateTime.toString(SystemConst.DEFAULT_DATE_FOMATTER_YEARMONTHDAY)));
                }
            }
        }
        return flag;
    }

}
